"""
HTTP客户端，支持所有HTTP请求类型、自定义HTTP头和自定义证书链
"""

import requests
from typing import Dict, Any, Optional, Union, Tuple


class HTTPException(Exception):
    """
    HTTP请求基础异常类
    """
    pass


class HTTPClient:
    """
    HTTP客户端类，支持所有HTTP请求类型、自定义HTTP头和自定义证书链
    """

    def __init__(self, verify_ssl: Union[bool, str] = True, cert: Optional[Union[str, Tuple[str, str]]] = None):
        """
        初始化HTTP客户端

        :param verify_ssl: SSL证书验证，可以是布尔值或证书路径
        :param cert: 客户端证书，可以是证书路径字符串或(证书路径, 密钥路径)元组
        """
        self.session = requests.Session()
        self.session.verify = verify_ssl
        if cert:
            self.session.cert = cert

    def set_headers(self, headers: Dict[str, str]) -> None:
        """
        设置默认HTTP头

        :param headers: HTTP头字典
        """
        self.session.headers.update(headers)

    def set_cert(self, cert: Union[str, Tuple[str, str]]) -> None:
        """
        设置客户端证书

        :param cert: 客户端证书，可以是证书路径字符串或(证书路径, 密钥路径)元组
        """
        self.session.cert = cert

    def set_verify_ssl(self, verify: Union[bool, str]) -> None:
        """
        设置SSL证书验证

        :param verify: SSL证书验证，可以是布尔值或证书路径
        """
        self.session.verify = verify

    def get(self, url: str, params: Optional[Dict[str, Any]] = None,
            headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送GET请求

        :param url: 请求URL
        :param params: URL参数
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('GET', url, params=params, headers=headers, timeout=timeout)

    def post(self, url: str, data: Optional[Any] = None, json: Optional[Dict[str, Any]] = None,
             headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送POST请求

        :param url: 请求URL
        :param data: 请求数据（可以是字符串、字节或文件对象等任意内容）
        :param json: JSON数据
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('POST', url, data=data, json=json, headers=headers, timeout=timeout)

    def put(self, url: str, data: Optional[Any] = None, json: Optional[Dict[str, Any]] = None,
            headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送PUT请求

        :param url: 请求URL
        :param data: 请求数据（可以是字符串、字节或文件对象等任意内容）
        :param json: JSON数据
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('PUT', url, data=data, json=json, headers=headers, timeout=timeout)

    def patch(self, url: str, data: Optional[Any] = None, json: Optional[Dict[str, Any]] = None,
              headers: Optional[Dict[str, str]] = None, timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送PATCH请求

        :param url: 请求URL
        :param data: 请求数据（可以是字符串、字节或文件对象等任意内容）
        :param json: JSON数据
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('PATCH', url, data=data, json=json, headers=headers, timeout=timeout)

    def delete(self, url: str, headers: Optional[Dict[str, str]] = None,
               timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送DELETE请求

        :param url: 请求URL
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('DELETE', url, headers=headers, timeout=timeout)

    def head(self, url: str, headers: Optional[Dict[str, str]] = None,
             timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送HEAD请求

        :param url: 请求URL
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('HEAD', url, headers=headers, timeout=timeout)

    def options(self, url: str, headers: Optional[Dict[str, str]] = None,
                timeout: Optional[Union[float, Tuple[float, float]]] = None) -> requests.Response:
        """
        发送OPTIONS请求

        :param url: 请求URL
        :param headers: HTTP头
        :param timeout: 超时设置
        :return: Response对象
        """
        return self._request('OPTIONS', url, headers=headers, timeout=timeout)

    def _request(self, method: str, url: str, **kwargs) -> requests.Response:
        """
        发送HTTP请求

        :param method: HTTP方法
        :param url: 请求URL
        :param kwargs: 其他参数
        :return: Response对象
        """
        try:
            response = self.session.request(method, url, **kwargs)
            return response
        except requests.exceptions.ConnectionError as e:
            raise HTTPException(f"连接错误: {str(e)}")
        except requests.exceptions.Timeout as e:
            raise HTTPException(f"请求超时: {str(e)}")
        except requests.exceptions.RequestException as e:
            raise HTTPException(f"请求异常: {str(e)}")

    def close(self) -> None:
        """
        关闭会话
        """
        self.session.close()

    def __enter__(self) -> 'HTTPClient':
        return self

    def __exit__(self, exc_type: Optional[type], exc_val: Optional[BaseException], exc_tb: Optional[Any]) -> None:
        self.close()